﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;
using System.Reflection;
using System.Diagnostics;//stopwatch必须
using System.Collections.Concurrent;
using System.Threading;

namespace CrackExcelPwd
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //取消跨线程检查.
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void btnSelect_Click(object sender, EventArgs e)//选择路径
        {
            string filePath = "";
            //创建文件弹出选择窗口（包括文件名）对象
            OpenFileDialog ofd = new OpenFileDialog();
            //判断选择的路径
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.txtSoundPath.Text = ofd.FileName.ToString();
            }
            filePath = this.txtSoundPath.Text;
        }


        private void button1_Click(object sender, EventArgs e)//开始破解
        {
            int selectquery = 0;//4个条件必须其一
            if (checkBox1.Checked){ selectquery++; }
            if (checkBox2.Checked) { selectquery++; }
            if (checkBox3.Checked) { selectquery++; }
            if (textBox1.Text != "") { selectquery++; }
            if (selectquery == 0) { MessageBox.Show("请选择条件值！"); return; }

            int selectquery2 = 0;//2个算法条件必须其一
            if (checkBox4.Checked) { selectquery2++; }
            if (checkBox5.Checked) { selectquery2++; }
            if (selectquery2 == 0) { MessageBox.Show("请选择一个算法！"); return; }

            Parallel.Invoke(
                () => workall_1(),
                () => workall_2(),
                () => workall_3(),
                () => workall_4(),
                () => workall_5(),
                () => workall_6(),
                () => workall_7(),
                () => workall_8(),
                () => workall_9(),
                () => workall_10()
                );
        }

        private void workall_1()
        {
            //excel1
            if (txtSoundPath.Text != "")
            {
                if (checkBox4.Checked == true)//分区
                {
                    Parallel.Invoke(() => run_partition(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, txtSoundPath.Text, 1));
                }
                if (checkBox5.Checked == true)//混淆
                {
                    Parallel.Invoke(() => run_random(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, txtSoundPath.Text, 1));
                }
            }
        }
        private void workall_2()
        {
            //excel2
            if (textBox2.Text != "")
            {
                if (checkBox4.Checked == true)//分区
                {
                    Parallel.Invoke(() => run_partition(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox2.Text, 2));
                }
                if (checkBox5.Checked == true)//混淆
                {
                    Parallel.Invoke(() => run_random(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox2.Text, 2));
                }
            }
        }
        private void workall_3()
        {
            //excel2
            if (textBox3.Text != "")
            {
                if (checkBox4.Checked == true)//分区
                {
                    Parallel.Invoke(() => run_partition(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox3.Text, 3));
                }
                if (checkBox5.Checked == true)//混淆
                {
                    Parallel.Invoke(() => run_random(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox3.Text, 3));
                }
            }
        }
        private void workall_4()
        {
            //excel2
            if (textBox4.Text != "")
            {
                if (checkBox4.Checked == true)//分区
                {
                    Parallel.Invoke(() => run_partition(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox4.Text, 4));
                }
                if (checkBox5.Checked == true)//混淆
                {
                    Parallel.Invoke(() => run_random(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox4.Text, 4));
                }
            }
        }
        private void workall_5()
        {
            //excel2
            if (textBox5.Text != "")
            {
                if (checkBox4.Checked == true)//分区
                {
                    Parallel.Invoke(() => run_partition(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox5.Text, 5));
                }
                if (checkBox5.Checked == true)//混淆
                {
                    Parallel.Invoke(() => run_random(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox5.Text, 5));
                }
            }
        }
        private void workall_6()
        {
            //excel2
            if (textBox6.Text != "")
            {
                if (checkBox4.Checked == true)//分区
                {
                    Parallel.Invoke(() => run_partition(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox6.Text, 6));
                }
                if (checkBox5.Checked == true)//混淆
                {
                    Parallel.Invoke(() => run_random(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox6.Text, 6));
                }
            }
        }
        private void workall_7()
        {
            //excel2
            if (textBox7.Text != "")
            {
                if (checkBox4.Checked == true)//分区
                {
                    Parallel.Invoke(() => run_partition(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox7.Text, 7));
                }
                if (checkBox5.Checked == true)//混淆
                {
                    Parallel.Invoke(() => run_random(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox7.Text, 7));
                }
            }
        }
        private void workall_8()
        {
            //excel2
            if (textBox8.Text != "")
            {
                if (checkBox4.Checked == true)//分区
                {
                    Parallel.Invoke(() => run_partition(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox8.Text, 8));
                }
                if (checkBox5.Checked == true)//混淆
                {
                    Parallel.Invoke(() => run_random(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox8.Text, 8));
                }
            }
        }
        private void workall_9()
        {
            //excel2
            if (textBox9.Text != "")
            {
                if (checkBox4.Checked == true)//分区
                {
                    Parallel.Invoke(() => run_partition(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox9.Text, 9));
                }
                if (checkBox5.Checked == true)//混淆
                {
                    Parallel.Invoke(() => run_random(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox9.Text, 9));
                }
            }
        }
        private void workall_10()
        {
            //excel2
            if (textBox10.Text != "")
            {
                if (checkBox4.Checked == true)//分区
                {
                    Parallel.Invoke(() => run_partition(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox10.Text, 10));
                }
                if (checkBox5.Checked == true)//混淆
                {
                    Parallel.Invoke(() => run_random(checkBox1.Checked, checkBox2.Checked, checkBox3.Checked, (int)numericUpDown1.Value, textBox1.Text, textBox10.Text, 10));
                }
            }
        }
        private bool FindPassword(string path,string sPassword, Microsoft.Office.Interop.Excel.Workbook oResult, Microsoft.Office.Interop.Excel.Application excel1)
        {
            try
            {
                //暴力破解密码，textBox1.Text的值是EXCEL文件路径名及文件名
                oResult = excel1.Application.Workbooks.Open
                    (path, Missing.Value, Missing.Value, Missing.Value, sPassword, Missing.Value,
                    Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value,
                    Missing.Value, Missing.Value, Missing.Value);
                excel1.Visible = false;
            }
            catch(Exception error)
            {
                //MessageBox.Show(error.ToString());
            }
            if (oResult != null)
            {
                //MessageBox.Show("密码是:'"+ sPassword + "'");
                //找到密码，密码就是sPassword
                return true;
            }
            else
            {
                //MessageBox.Show("密码不正确!");
                //密码不正确
                return false;
            }
        }

        //普通for串行asc方式计算
        private void run(bool cb1, bool cb2, bool cb3, int len, string str_pwd,string path)//破解密码
        {
            //设置EXCEL操作对象
            Microsoft.Office.Interop.Excel.Workbook oResult = null;
            Microsoft.Office.Interop.Excel.Application excel1 = new Microsoft.Office.Interop.Excel.Application(); //引用Excel对象

            //开始设置密码字典
            string[] str_cb1 = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
            string[] str_cb2 = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "g", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "G", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
            string[] str_cb3 = {"!","@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "+", "=", "_", "`", "~", "[", "]", "{", "}", "|", "<", ",", ">", ".", "?", "/" };
            string[] str= { };
            if (cb1)//如果勾选了数字
            {
                str=str.Concat(str_cb1).ToArray();//拼接数组
            }
            if (cb2)//如果勾选了英文
            {
                str = str.Concat(str_cb2).ToArray();//拼接数组
            }
            if (cb3)//如果勾选了数字
            {
                str = str.Concat(str_cb3).ToArray();//拼接数组
            }
            if (str_pwd!="")//如果勾选了数字
            {
                str_pwd = str_pwd.Replace(" ", "").Replace("，", ",").Trim(new char[] { ',' });//去掉空格，将中文逗号换为英文逗号,去除两端的逗号
                string[] strArray = str_pwd.Split(',');//字符串转数组
                str = strArray.Concat(str).ToArray();//拼接数组,注意，此处是将自定义字符串放到数组最前面，优先匹配
            }
            //string tempstrs = "";
            //foreach (string ss in str) { tempstrs += ss + "||"; }
            //MessageBox.Show(tempstrs.ToString()); return;
            string temppwd = "";
            len = len + 1;//数字加1才是位数
            DateTime startTime = DateTime.Now;//得到循环开始的时间点，显示用时
            int num = 0;//循环执行的总计数
            for(int i=1;i<len; i++)//密码位数循环，从1到len
            {
                for (int j = 0; j < str.Length; j++)//str字符串内数组元素的穷举排列组合
                {
                    if (i == 1)//1位密码str字符串内数组元素的穷举排列组合
                    {
                        temppwd = str[j];
                        //MessageBox.Show(temppwd);
                        if (FindPassword(path,temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                    }
                    if (i == 2)//2位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            temppwd = str[j] + str[m];
                            //MessageBox.Show(temppwd);
                            if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                        }
                    }
                    if (i == 3)//3位密码str字符串内数组元素的穷举排列组合
                    {
                        for(int m=0; m<str.Length;m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                temppwd = str[j] + str[m] + str[n];
                                //MessageBox.Show(temppwd);
                                if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                            }
                        }
                    }
                    if (i == 4)//4位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    temppwd = str[j] + str[m] + str[n] + str[p];
                                    //MessageBox.Show(temppwd);
                                    if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                                }
                            }
                        }
                    }
                    if (i == 5)//5位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    for (int q = 0; q < str.Length; q++)
                                    {
                                        temppwd = str[j] + str[m] + str[n] + str[p] + str[q];
                                        //MessageBox.Show(temppwd);
                                        if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                                    }
                                }
                            }
                        }
                    }
                    if (i == 6)//6位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    for (int q = 0; q < str.Length; q++)
                                    {
                                        for (int r = 0; r < str.Length; r++)
                                        {
                                            temppwd = str[j] + str[m] + str[n] + str[p] + str[q] + str[r];
                                            //MessageBox.Show(temppwd);
                                            if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        //普通for串行desc方式计算
        private void run_desc(bool cb1, bool cb2, bool cb3, int len, string str_pwd, string path)//破解密码
        {
            //设置EXCEL操作对象
            Microsoft.Office.Interop.Excel.Workbook oResult = null;
            Microsoft.Office.Interop.Excel.Application excel1 = new Microsoft.Office.Interop.Excel.Application(); //引用Excel对象

            //开始设置密码字典
            string[] str_cb1 = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
            string[] str_cb2 = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "g", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "G", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
            string[] str_cb3 = { "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "+", "=", "_", "`", "~", "[", "]", "{", "}", "|", "<", ",", ">", ".", "?", "/" };
            string[] str = { };
            if (cb1)//如果勾选了数字
            {
                str = str.Concat(str_cb1).ToArray();//拼接数组
            }
            if (cb2)//如果勾选了英文
            {
                str = str.Concat(str_cb2).ToArray();//拼接数组
            }
            if (cb3)//如果勾选了数字
            {
                str = str.Concat(str_cb3).ToArray();//拼接数组
            }
            if (str_pwd != "")//如果勾选了数字
            {
                str_pwd = str_pwd.Replace(" ", "").Replace("，", ",").Trim(new char[] { ',' });//去掉空格，将中文逗号换为英文逗号,去除两端的逗号
                string[] strArray = str_pwd.Split(',');//字符串转数组
                str = strArray.Concat(str).ToArray();//拼接数组,注意，此处是将自定义字符串放到数组最前面，优先匹配
            }
            //string tempstrs = "";
            //foreach (string ss in str) { tempstrs += ss + "||"; }
            //MessageBox.Show(tempstrs.ToString()); return;
            string temppwd = "";
            len = len + 1;//数字加1才是位数
            DateTime startTime = DateTime.Now;//得到循环开始的时间点，显示用时
            int num = 0;//循环执行的总计数
            for (int i = 1; i < len; i++)//密码位数循环，从1到len
            {
                for (int j = str.Length-1; j >0; j--)//str字符串内数组元素的穷举排列组合
                {
                    if (i == 1)//1位密码str字符串内数组元素的穷举排列组合
                    {
                        temppwd = str[j];
                        //MessageBox.Show(temppwd);
                        if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                    }
                    if (i == 2)//2位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            temppwd = str[j] + str[m];
                            //MessageBox.Show(temppwd);
                            if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                        }
                    }
                    if (i == 3)//3位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                temppwd = str[j] + str[m] + str[n];
                                //MessageBox.Show(temppwd);
                                if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                            }
                        }
                    }
                    if (i == 4)//4位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    temppwd = str[j] + str[m] + str[n] + str[p];
                                    //MessageBox.Show(temppwd);
                                    if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                                }
                            }
                        }
                    }
                    if (i == 5)//5位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    for (int q = 0; q < str.Length; q++)
                                    {
                                        temppwd = str[j] + str[m] + str[n] + str[p] + str[q];
                                        //MessageBox.Show(temppwd);
                                        if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                                    }
                                }
                            }
                        }
                    }
                    if (i == 6)//6位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    for (int q = 0; q < str.Length; q++)
                                    {
                                        for (int r = 0; r < str.Length; r++)
                                        {
                                            temppwd = str[j] + str[m] + str[n] + str[p] + str[q] + str[r];
                                            //MessageBox.Show(temppwd);
                                            if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("密码是:'" + temppwd + "'"); excel1.Quit(); return; }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        //整体str做Random方式计算
        private void run_random(bool cb1, bool cb2, bool cb3, int len, string str_pwd, string path,int work_id)//破解密码
        {
            //设置EXCEL操作对象
            Microsoft.Office.Interop.Excel.Workbook oResult = null;
            Microsoft.Office.Interop.Excel.Application excel1 = new Microsoft.Office.Interop.Excel.Application(); //引用Excel对象

            //开始设置密码字典
            string[] str_cb1 = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
            string[] str_cb2 = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "g", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "G", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
            string[] str_cb3 = { "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "+", "=", "_", "`", "~", "[", "]", "{", "}", "|", "<", ",", ">", ".", "?", "/" };
            string[] str = { };
            if (cb1)//如果勾选了数字
            {
                str = str.Concat(str_cb1).ToArray();//拼接数组
            }
            if (cb2)//如果勾选了英文
            {
                str = str.Concat(str_cb2).ToArray();//拼接数组
            }
            if (cb3)//如果勾选了数字
            {
                str = str.Concat(str_cb3).ToArray();//拼接数组
            }
            if (str_pwd != "")//如果勾选了数字
            {
                str_pwd = str_pwd.Replace(" ", "").Replace("，", ",").Trim(new char[] { ',' });//去掉空格，将中文逗号换为英文逗号,去除两端的逗号
                string[] strArray = str_pwd.Split(',');//字符串转数组
                str = strArray.Concat(str).ToArray();//拼接数组,注意，此处是将自定义字符串放到数组最前面，优先匹配
            }
            Item<string> disrupter = new Item<string>(str);
            str = disrupter.GetDisruptedItems();
            //string tempstrs = "";
            //foreach (string ss in str) { tempstrs += ss + "||"; }
            //MessageBox.Show(tempstrs.ToString()); return;

            string temppwd = "";
            len = len + 1;//数字加1才是位数
            DateTime startTime = DateTime.Now;//得到循环开始的时间点，显示用时
            int num = 0;//循环执行的总计数
            for (int i = 1; i < len; i++)//密码位数循环，从1到len
            {
                for (int j=0;j<str.Length;j++)//str字符串内数组元素的穷举排列组合
                {
                    if (i == 1)//1位密码str字符串内数组元素的穷举排列组合
                    {
                        temppwd = str[j];
                        //MessageBox.Show(temppwd);
                        if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务" + work_id + "破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                        num++;
                        progress(startTime, num,work_id);
                    }
                    if (i == 2)//2位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            temppwd = str[j] + str[m];
                            //MessageBox.Show(temppwd);
                            if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务" + work_id + "破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                            num++;
                            progress(startTime, num, work_id);
                        }
                    }
                    if (i == 3)//3位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                temppwd = str[j] + str[m] + str[n];
                                //MessageBox.Show(temppwd);
                                if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务" + work_id + "破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                                num++;
                                progress(startTime, num, work_id);
                            }
                        }
                    }
                    if (i == 4)//4位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    temppwd = str[j] + str[m] + str[n] + str[p];
                                    //MessageBox.Show(temppwd);
                                    if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务" + work_id + "破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                                    num++;
                                    progress(startTime, num, work_id);
                                }
                            }
                        }
                    }
                    if (i == 5)//5位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    for (int q = 0; q < str.Length; q++)
                                    {
                                        temppwd = str[j] + str[m] + str[n] + str[p] + str[q];
                                        //MessageBox.Show(temppwd);
                                        if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务" + work_id + "破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                                        num++;
                                        progress(startTime, num, work_id);
                                    }
                                }
                            }
                        }
                    }
                    if (i == 6)//6位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    for (int q = 0; q < str.Length; q++)
                                    {
                                        for (int r = 0; r < str.Length; r++)
                                        {
                                            temppwd = str[j] + str[m] + str[n] + str[p] + str[q] + str[r];
                                            //MessageBox.Show(temppwd);
                                            if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务" + work_id + "破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                                            num++;
                                            progress(startTime, num, work_id);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        //对str分区后对每个区做Random方式计算
        private void run_partition(bool cb1, bool cb2, bool cb3, int len, string str_pwd, string path, int work_id)//破解密码
        {
            //设置EXCEL操作对象
            Microsoft.Office.Interop.Excel.Workbook oResult = null;
            Microsoft.Office.Interop.Excel.Application excel1 = new Microsoft.Office.Interop.Excel.Application(); //引用Excel对象

            //开始设置密码字典
            string[] str_cb1 = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
            string[] str_cb2 = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "g", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "G", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
            string[] str_cb3 = { "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "+", "=", "_", "`", "~", "[", "]", "{", "}", "|", "<", ",", ">", ".", "?", "/" };
            string[] str = { };
            if (cb1)//如果勾选了数字
            {
                str = str.Concat(str_cb1).ToArray();//拼接数组
            }
            if (cb2)//如果勾选了英文
            {
                str = str.Concat(str_cb2).ToArray();//拼接数组
            }
            if (cb3)//如果勾选了数字
            {
                str = str.Concat(str_cb3).ToArray();//拼接数组
            }
            if (str_pwd != "")//如果勾选了数字
            {
                str_pwd = str_pwd.Replace(" ", "").Replace("，", ",").Trim(new char[] { ',' });//去掉空格，将中文逗号换为英文逗号,去除两端的逗号
                string[] strArray = str_pwd.Split(',');//字符串转数组
                str = strArray.Concat(str).ToArray();//拼接数组,注意，此处是将自定义字符串放到数组最前面，优先匹配
            }
            //string tempstrs = "";
            //foreach (string ss in str) { tempstrs += ss + "||"; }
            //MessageBox.Show(tempstrs.ToString()); return;

            string temppwd = "";
            len = len + 1;//数字加1才是位数
            DateTime startTime = DateTime.Now;//得到循环开始的时间点，显示用时
            int num = 0;//循环执行的总计数

            //平均分区
            int group = 0;//分成N个数组,根据用户选择了多少个excel得出
            if (txtSoundPath.Text != "") { group++; }
            if (textBox2.Text != "") { group++; }
            if (textBox3.Text != "") { group++; }
            if (textBox4.Text != "") { group++; }
            if (textBox5.Text != "") { group++; }
            if (textBox6.Text != "") { group++; }
            if (textBox7.Text != "") { group++; }
            if (textBox8.Text != "") { group++; }
            if (textBox9.Text != "") { group++; }
            if (textBox10.Text != "") { group++; }
            List<List<string>> data = new List<List<string>>();
            int count = str.Length / group;//新数组分多少个元素
            for (int i = 0; i < group; i++)
            {
                List<string> lst = new List<string>();
                for (int j = i * count; j < i * count + count; j++)
                {
                    lst.Add(str[j]);
                }
                if (i == group - 1)
                {
                    for (int j = i * count + count; j < str.Length; j++)
                    {
                        lst.Add(str[j]);
                    }
                }
                data.Add(lst);
            }

            string[] str_temp = data[work_id-1].ToArray();//得到最新分区后的数组，赋值给str
            //Item<string> disrupter = new Item<string>(str_temp);//打乱位置
            //str_temp = disrupter.GetDisruptedItems();

            for (int i = 1; i < len; i++)//密码位数循环，从1到len
            {
                for (int j = 0; j < str_temp.Length; j++)//str_temp字符串内数组元素的穷举排列组合，开始坐标start和结束end坐标
                {
                    if (i == 1)//1位密码str字符串内数组元素的穷举排列组合
                    {
                        temppwd = str_temp[j];
                        //MessageBox.Show(temppwd);
                        if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务"+ work_id+"破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                        num++;
                        progress(startTime, num, work_id);
                    }
                    if (i == 2)//2位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            temppwd = str_temp[j] + str[m];
                            //MessageBox.Show(temppwd);
                            if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务" + work_id + "破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                            num++;
                            progress(startTime, num, work_id);
                            System.Windows.Forms.Application.DoEvents();
                        }
                    }
                    if (i == 3)//3位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                temppwd = str_temp[j] + str[m] + str[n];
                                //MessageBox.Show(temppwd);
                                if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务" + work_id + "破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                                num++;
                                progress(startTime, num, work_id);
                                System.Windows.Forms.Application.DoEvents();
                            }
                        }
                    }
                    if (i == 4)//4位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    temppwd = str_temp[j] + str[m] + str[n] + str[p];
                                    //MessageBox.Show(temppwd);
                                    if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务" + work_id + "破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                                    num++;
                                    progress(startTime, num, work_id);
                                    System.Windows.Forms.Application.DoEvents();
                                }
                            }
                        }
                    }
                    if (i == 5)//5位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    for (int q = 0; q < str.Length; q++)
                                    {
                                        temppwd = str_temp[j] + str[m] + str[n] + str[p] + str[q];
                                        //MessageBox.Show(temppwd);
                                        if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务" + work_id + "破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                                        num++;
                                        progress(startTime, num, work_id);
                                        System.Windows.Forms.Application.DoEvents();
                                    }
                                }
                            }
                        }
                    }
                    if (i == 6)//6位密码str字符串内数组元素的穷举排列组合
                    {
                        for (int m = 0; m < str.Length; m++)//针对数组str做排列组合 10的二次方
                        {
                            for (int n = 0; n < str.Length; n++)
                            {
                                for (int p = 0; p < str.Length; p++)
                                {
                                    for (int q = 0; q < str.Length; q++)
                                    {
                                        for (int r = 0; r < str.Length; r++)
                                        {
                                            temppwd = str_temp[j] + str[m] + str[n] + str[p] + str[q] + str[r];
                                            //MessageBox.Show(temppwd);
                                            if (FindPassword(path, temppwd, oResult, excel1)) { MessageBox.Show("任务" + work_id + "破获的密码是:'" + temppwd + "'"); excel1.Quit(); Environment.Exit(0); }
                                            num++;
                                            progress(startTime, num, work_id);
                                            System.Windows.Forms.Application.DoEvents();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }


        private void progress(DateTime startTime,int num,int work_id)//显示进度
        {
            if (work_id == 1)
            {
                TimeSpan span = DateTime.Now - startTime;
                double second = span.TotalSeconds;
                labTime.Text = "已用时：" + second.ToString("F2") + "秒";
                label2.Text = "已破解量：" + num.ToString() + "个";
            }
            if (work_id == 2)
            {
                TimeSpan span = DateTime.Now - startTime;
                double second = span.TotalSeconds;
                label19.Text = "已用时：" + second.ToString("F2") + "秒";
                label18.Text = "已破解量：" + num.ToString() + "个";
            }
            if (work_id == 3)
            {
                TimeSpan span = DateTime.Now - startTime;
                double second = span.TotalSeconds;
                label21.Text = "已用时：" + second.ToString("F2") + "秒";
                label20.Text = "已破解量：" + num.ToString() + "个";
            }
            if (work_id == 4)
            {
                TimeSpan span = DateTime.Now - startTime;
                double second = span.TotalSeconds;
                label23.Text = "已用时：" + second.ToString("F2") + "秒";
                label22.Text = "已破解量：" + num.ToString() + "个";
            }
            if (work_id == 5)
            {
                TimeSpan span = DateTime.Now - startTime;
                double second = span.TotalSeconds;
                label25.Text = "已用时：" + second.ToString("F2") + "秒";
                label24.Text = "已破解量：" + num.ToString() + "个";
            }
            if (work_id == 6)
            {
                TimeSpan span = DateTime.Now - startTime;
                double second = span.TotalSeconds;
                label27.Text = "已用时：" + second.ToString("F2") + "秒";
                label26.Text = "已破解量：" + num.ToString() + "个";
            }
            if (work_id == 7)
            {
                TimeSpan span = DateTime.Now - startTime;
                double second = span.TotalSeconds;
                label29.Text = "已用时：" + second.ToString("F2") + "秒";
                label28.Text = "已破解量：" + num.ToString() + "个";
            }
            if (work_id == 8)
            {
                TimeSpan span = DateTime.Now - startTime;
                double second = span.TotalSeconds;
                label31.Text = "已用时：" + second.ToString("F2") + "秒";
                label30.Text = "已破解量：" + num.ToString() + "个";
            }
            if (work_id == 9)
            {
                TimeSpan span = DateTime.Now - startTime;
                double second = span.TotalSeconds;
                label33.Text = "已用时：" + second.ToString("F2") + "秒";
                label32.Text = "已破解量：" + num.ToString() + "个";
            }
            if (work_id == 10)
            {
                TimeSpan span = DateTime.Now - startTime;
                double second = span.TotalSeconds;
                label35.Text = "已用时：" + second.ToString("F2") + "秒";
                label34.Text = "已破解量：" + num.ToString() + "个";
            }
        }

        //将数组元素位置打乱
        //泛型类
        class Item<T>
        {
            T[] item;
            //构造函数
            public Item(T[] obj)
            {
                item = new T[obj.Length];
                for (int i = 0; i < obj.Length; i++)
                {
                    item[i] = obj[i];
                }
            }
            public Type ShowType() { return typeof(T); } //返回类型
            public T[] GetItems() { return item; } //返回原数组
                                                   //返回打乱顺序后的数组
            public T[] GetDisruptedItems()
            {
                //生成一个新数组：用于在之上计算和返回
                T[] temp;
                temp = new T[item.Length];
                for (int i = 0; i < temp.Length; i++) { temp[i] = item[i]; }
                //打乱数组中元素顺序
                Random rand = new Random(DateTime.Now.Millisecond);
                for (int i = 0; i < temp.Length; i++)
                {
                    int x, y; T t;
                    x = rand.Next(0, temp.Length);
                    do
                    {
                        y = rand.Next(0, temp.Length);
                    } while (y == x);
                    t = temp[x];
                    temp[x] = temp[y];
                    temp[y] = t;
                }
                return temp;
            }
        }

        private void button2_Click(object sender, EventArgs e)//选择2
        {
            string filePath = "";
            //创建文件弹出选择窗口（包括文件名）对象
            OpenFileDialog ofd = new OpenFileDialog();
            //判断选择的路径
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.textBox2.Text = ofd.FileName.ToString();
            }
            filePath = this.textBox2.Text;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            string filePath = "";
            //创建文件弹出选择窗口（包括文件名）对象
            OpenFileDialog ofd = new OpenFileDialog();
            //判断选择的路径
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.textBox3.Text = ofd.FileName.ToString();
            }
            filePath = this.textBox3.Text;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            string filePath = "";
            //创建文件弹出选择窗口（包括文件名）对象
            OpenFileDialog ofd = new OpenFileDialog();
            //判断选择的路径
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.textBox4.Text = ofd.FileName.ToString();
            }
            filePath = this.textBox4.Text;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            string filePath = "";
            //创建文件弹出选择窗口（包括文件名）对象
            OpenFileDialog ofd = new OpenFileDialog();
            //判断选择的路径
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.textBox5.Text = ofd.FileName.ToString();
            }
            filePath = this.textBox5.Text;
        }

        private void button6_Click(object sender, EventArgs e)
        {
            string filePath = "";
            //创建文件弹出选择窗口（包括文件名）对象
            OpenFileDialog ofd = new OpenFileDialog();
            //判断选择的路径
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.textBox6.Text = ofd.FileName.ToString();
            }
            filePath = this.textBox6.Text;
        }

        private void button7_Click(object sender, EventArgs e)
        {
            string filePath = "";
            //创建文件弹出选择窗口（包括文件名）对象
            OpenFileDialog ofd = new OpenFileDialog();
            //判断选择的路径
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.textBox7.Text = ofd.FileName.ToString();
            }
            filePath = this.textBox7.Text;
        }

        private void button8_Click(object sender, EventArgs e)
        {
            string filePath = "";
            //创建文件弹出选择窗口（包括文件名）对象
            OpenFileDialog ofd = new OpenFileDialog();
            //判断选择的路径
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.textBox8.Text = ofd.FileName.ToString();
            }
            filePath = this.textBox8.Text;
        }

        private void button9_Click(object sender, EventArgs e)
        {
            string filePath = "";
            //创建文件弹出选择窗口（包括文件名）对象
            OpenFileDialog ofd = new OpenFileDialog();
            //判断选择的路径
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.textBox9.Text = ofd.FileName.ToString();
            }
            filePath = this.textBox9.Text;
        }

        private void button10_Click(object sender, EventArgs e)
        {
            string filePath = "";
            //创建文件弹出选择窗口（包括文件名）对象
            OpenFileDialog ofd = new OpenFileDialog();
            //判断选择的路径
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                this.textBox10.Text = ofd.FileName.ToString();
            }
            filePath = this.textBox10.Text;
        }

        private void button11_Click(object sender, EventArgs e)//停止
        {
            Environment.Exit(0);
        }
    }
}
